// CuBlas.Net.h

#pragma once

#include "cublas.h"

using namespace System;
using namespace System::Runtime::InteropServices;

namespace CuBlasNet {

	public ref class Blas
	{
	public:
		static Blas()
		{
			cublasStatus status = cublasInit();

			if (status != CUBLAS_STATUS_SUCCESS)
			{
				throw gcnew InvalidOperationException("Couldn't initialize CUBLAS");
			}
		}

		int IndexOfMax(array<float>^ x, int startElement, int skipElements);
		int IndexOfMin(array<float>^ x, int startElement, int skipElements);
		float AbsValueSum(array<float>^ x, int startElement, int skipElements);
		void Axpy(float alpha, array<float>^ x, int startElementX, int skipElementsX, array<float>^ y, int startElementY, int skipElementsY);
		void Copy(array<float>^ x, int startElementX, int skipElementsX, array<float>^ y, int startElementY, int skipElementsY);
		void Dot(array<float>^ x, int startElementX, int skipElementsX, array<float>^ y, int startElementY, int skipElementsY);
		float Norm2(array<float>^ x, int startElement, int skipElements);
		void Rotate(array<float>^ x, int startElementX, int skipElementsX, array<float>^ y, int startElementY, int skipElementsY, float cos, float sin);
		void RotateG(float% sa, float% sb, [Out] float% sc, [Out] float% ss);
		void RotateM(array<float>^ x, int skipElementsX, int startElementX, array<float>^ y, int startElementY, int skipElementsY, array<float>^ params);
		void RotateMG(float% sd1, float% sd2, float% sx1, float sy1, array<float>^% params);
		void Scale(float alpha, array<float>^ x, int startElement, int skipElements);
		void Swap(array<float>^ x, int startElementX, int skipElementsX, array<float>^ y, int startElementY, int skipElementsY);

		// BLAS 2 and BLAS 3 functions not yet implemented
	};
}
